import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import * as dat from 'dat.gui'


let scene, camera, renderer
let mixer //定义混合器
let actions = {} //定义一个对象来装行为
let activeAction  //定义当前选中的行为
let activeActionObjects = { state: 'Walking' } //用来操作gui的
let clock = new THREE.Clock()
let previousAction


initRenderer()
initCamera()
initScene()
initLight()
initAxesHelper()
initMeshes()

window.addEventListener('resize', onWindowResize);

function initRenderer() {
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight)
    //颜色在不同设备和平台上看起来是一致的
    renderer.outputEncoding = THREE.sRGBEncoding
    document.body.appendChild(renderer.domElement)
}

function initCamera(params) {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 100)
    camera.position.set(-5, 3, 10)
    camera.lookAt(new THREE.Vector3(0,2,0))
}

function initScene(params) {
    scene = new THREE.Scene()
    scene.background = new THREE.Color(0xe0e0e0)
    scene.fog = new THREE.Fog(0xe0e0e0,20,100)
}

function initAxesHelper(params) {
    scene.add(new THREE.AxesHelper(2))
}

function initMeshes() {

//plane
    const planegeometry = new THREE.PlaneGeometry(2000, 2000)
    const planematerial = new THREE.MeshPhongMaterial({
        color:0x999999
    })
    const plane = new THREE.Mesh(planegeometry, planematerial)
    plane.rotation.x = -Math.PI / 2
    scene.add(plane)

    //地面添加网格
    const grid = new THREE.GridHelper(100, 40, 0, 0)
    grid.material.transparent = true
    grid.material.opacity = 0.2
    scene.add(grid)

    
    


    const loader = new GLTFLoader();
    loader.load('models/gltf/RobotExpressive/RobotExpressive.glb',function (gltf) {
        console.log(gltf);
        const model = gltf.scene
        scene.add(model)

        //动画
        const clips = gltf.animations
        mixer = new THREE.AnimationMixer(model)
        // activeAction = mixer.clipAction(clips[0])
        // activeAction.play()

        //morph
        const face = model.getObjectByName('Head_4')
        // console.log(face);
        // console.log(face.morphTargetDirectionary);
        // console.log(face.morphTargetInfluences);
        // face.morphTargetInfluences[2] = 1
        initGUI(model,clips,face)
        animate()


    }
    )
}

function initGUI(model,clips,face) {
    let gui = new dat.GUI()
    const actionNames = [];
    const loopMany = ['Walking', 'Running', 'Idle', 'Dance'];
    for (let i = 0; i < clips.length; i++) { 
        const clip = clips[i];
        const action = mixer.clipAction(clip)
        actions[clip.name] = action
        if (!loopMany.includes(clip.name)) {
            action.clampWhenFinished = true
            //保存最后的动作
            action.loop = THREE.LoopOnce
        }
        actionNames.push(clip.name)
    }
    console.log(actions);
    console.log(actionNames);
    activeAction = actions['Walking'];
    activeAction.play()
    
    //调试器1动画选取
    const clipFolder = gui.addFolder('动画');
    clipFolder.add(activeActionObjects, 'state').options(actionNames).onChange(
        function () {
            // console.log(activeActionObjects.state);
            const nextAction = activeActionObjects.state;
            fadeToAction(nextAction, 0.5)
        }
    );
//调试器2 morph
const morphFolder = gui.addFolder('情绪')
const morghNames = Object.keys(face.morphTargetDictionary);
for (let i = 0; i < morghNames.length; i++) { 
    morphFolder.add(face.morphTargetInfluences,i,0,1,0.01).name(morghNames[i])
    }
    
    //调试器3 动画穿插
    const state = ['Idel', 'Walking', 'Dance', 'Death', 'Sitting', 'Standing']
    const complexFolder = gui.addFolder('穿插')
    complexFolder.add(activeActionObjects, 'state').options(state).onChange(
        function (params) {
            const nextActionName = activeActionObjects.state;
            fadeToAction(nextActionName,0.5 )
        }
    )
    const emotes = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp'];
    const api = {}
    for (let i = 0; i < emotes.length; i++) { 
        const name = emotes[i]
        api[name] = function (params) {
            fadeToAction(name, 0.2)
            mixer.addEventListener('finish', restoreState)
        }
        complexFolder.add(api,name)
    }
    function restoreState(params) {
        mixer.removeEventListener('finish', restoreState);
        fadeToAction(activeActionObjects.state,0.2)
    }
}



function fadeToAction(name,duration) {
    previousAction = activeAction;
    activeAction = actions[name];
    previousAction.fadeOut(duration);
    //不重置动作选过的动作就用不了
    activeAction.fadeIn(duration).reset().play()
}

function initLight(params) {
    const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444)
    scene.add(hemiLight)

    const dirLight = new THREE.DirectionalLight(0xffffff)
    dirLight.position.set(0, 20, 10)
    scene.add(dirLight)
}



function onWindowResize(params) {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth,window.innerHeight)
}

function animate(params) {
    const delta = clock.getDelta()
    mixer.update(delta)
    requestAnimationFrame(animate)
    renderer.render(scene, camera)
}